/*
 * GraphicUtil.java
 *
 * Created on Jun 12, 2007, 6:37:29 PM
 *
 * Copyright (c) 2007 Daniel Gronau
 *
 * This file is part of KanjiTori.
 *
 * KanjiTori is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * KanjiTori is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 *
 */

package kanjitori.util;

import com.jme.image.Image;
import com.jme.image.Texture;
import com.jme.renderer.ColorRGBA;
import com.jme.renderer.Renderer;
import com.jme.scene.Controller;
import com.jme.scene.Node;
import com.jme.scene.Skybox;
import com.jme.scene.Spatial;
import com.jme.scene.state.AlphaState;
import com.jme.scene.state.CullState;
import com.jme.scene.state.MaterialState;
import com.jme.scene.state.RenderState;
import com.jme.scene.state.TextureState;
import com.jme.scene.state.ZBufferState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author DGronau
 */
public class GraphicUtil {
    
    private static AlphaState asTransparent;
    private static ZBufferState zState;
    
    /** Static class */
    private GraphicUtil() {
    }
    
    public static void cleanTexture(Spatial s) {
        TextureState ts = (TextureState)s.getRenderState(RenderState.RS_TEXTURE);
        if(ts != null) {
            ts.getTexture().setImage(null);
            TextureManager.releaseTexture(ts.getTexture());
            ts.deleteAll(true);
            s.clearRenderState(RenderState.RS_TEXTURE);
        }
        if(s instanceof Node) {
            ArrayList<Spatial> children = ((Node)s).getChildren();
            if(children != null) {
                for(Spatial child : children) {
                    cleanTexture(child);
                }
            }
        }
    }
    
    @SuppressWarnings("unchecked")
    public static void removeControllers(final Spatial spatial) {
                List<Controller> controllers = spatial.getControllers();
                for (Controller controller : controllers) {
                    controller.setActive(false);
                }
                for (int i = controllers.size() - 1; i >= 0; i--) {
                   spatial.removeController(i);
                }
    }
    
    public static AlphaState getTransparence() {
        if (asTransparent == null) {
            asTransparent = getRenderer().createAlphaState();
            asTransparent.setBlendEnabled(true);
            asTransparent.setSrcFunction(AlphaState.SB_SRC_ALPHA);
            asTransparent.setDstFunction(AlphaState.DB_ONE_MINUS_SRC_ALPHA);
            asTransparent.setEnabled(true);
        }
        return asTransparent;
    }
    
    public static TextureState loadTexture(String texture, boolean compressed) {
        TextureState ts = getRenderer().createTextureState();
        Texture t = compressed
                ? TextureManager.loadTexture(texture, Texture.MM_LINEAR, Texture.FM_LINEAR, ts.getMaxAnisotropic(), true)
                : TextureManager.loadTexture(texture, Texture.MM_LINEAR, Texture.FM_LINEAR, Image.GUESS_FORMAT_NO_S3TC,
                ts.getMaxAnisotropic(), true);
        if (t == null) {
            TextureManager.loadTexture("data/redcross.png", Texture.MM_LINEAR, Texture.FM_LINEAR, ts.getMaxAnisotropic(), true);
        }
        ts.setTexture(t);
        return ts;
    }
    
    public static TextureState loadTexture(java.awt.Image image) {
        TextureState ts = getRenderer().createTextureState();
        Texture t = TextureManager.loadTexture(image, Texture.MM_LINEAR, Texture.MM_LINEAR, ts.getMaxAnisotropic(), true);
        ts.setTexture(t);
        return ts;
    }
    
    public static MaterialState getMaterialState(ColorRGBA color) {
        MaterialState mat = getRenderer().createMaterialState();
        mat.setEmissive(color == null ? new ColorRGBA(0.5f, 0.5f, 0.5f, 1) : color);
        return mat;
    }
    
    public static CullState getCullState(int mode) {
        CullState cs = getRenderer().createCullState();
        cs.setCullMode(mode);
        cs.setEnabled(true);
        return cs;
    }
    
    public static ZBufferState getZState() {
        if (zState == null) {
            zState = getRenderer().createZBufferState();
            zState.setEnabled( true );
            zState.setFunction( ZBufferState.CF_ALWAYS);
        }
        return zState;
    }
    
    public static Skybox getSkybox(String... textures) {
        Skybox skybox = new Skybox("skybox", 200, 200, 200);
        for (int i = 0; i < 6; i++) {
            Texture tex = TextureManager.loadTexture(
                    textures[i], Texture.MM_LINEAR, Texture.FM_LINEAR,
                    Image.GUESS_FORMAT_NO_S3TC, 1, true);
            skybox.setTexture(i, tex);
        }
        return skybox;
    }
    
    public static Skybox getDefaultSkybox() {
        return getSkybox("data/sky_ft.png",
                "data/sky_bk.png",
                "data/sky_lf.png",
                "data/sky_rt.png",
                "data/sky_up.png",
                "data/sky_dn.png");
    }
    
    private static Renderer getRenderer() {
        return DisplaySystem.getDisplaySystem().getRenderer();
    }
}
